'use strict';
import calendar from './calendar.js';

export const DAYTIME = 24 * 60 * 60 * 1000;
export const WEEKCN = '日一二三四五六';
export const DAYCN = '一二三四五六七八九十';
export const DAYUNITCN = '初十廿卅';
export const MONTHCN = '正月,二月,三月,四月,五月,六月,七月,八月,九月,十月,冬月,腊月'.split(',');

export interface iBaseDate {
  lYear: number;
  lMonth: number;
  lDay: number;
  Animal: string;
  IMonthCn: string;
  IDayCn: string;
  cYear: number;
  cMonth: number;
  cDay: number;
  gzYear: string;
  gzMonth: string;
  gzDay: string;
  isToday: boolean;
  isLeap: boolean;
  nWeek: number;
  ncWeek: string;
  isTerm: boolean;
  Term: null | string;
  astro: string;
}

export interface baseDate extends iBaseDate {
  time: number;
  year: number;
  month: number;
  day: number;
  hour: number;
  minute: number;
  second: number;
  week: number;
  weekEn: string;
}

export enum baseDateUnit {
  year,
  month,
  day,
  hour,
  minute,
  second,
}

export enum WEEKEN {
  Sunday,
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday,
}

export const parseDate = (date: number | string | Date): baseDate => {
  try {
    const now = new Date(date);
    const iDate: iBaseDate = calendar.solar2lunar(now.getFullYear(), now.getMonth() + 1, now.getDate());
    return Object.assign(
      {
        time: now.getTime(),
        year: now.getFullYear(),
        month: now.getMonth(),
        day: now.getDate(),
        hour: now.getHours(),
        minute: now.getMinutes(),
        second: now.getSeconds(),
        week: now.getDay(),
        weekEn: WEEKEN[now.getDay()],
      },
      iDate,
    );
  } catch (err: any) {
    throw new Error(err);
  }
};

export const NOW = parseDate(new Date());

export const getFirstDayInMonth = (base: baseDate): baseDate => {
  base.day = 1;
  return parseDate(new Date(base.year, base.month, base.day));
};

export const changeDate = (base: baseDate, unit: baseDateUnit, span: number): baseDate => {
  const unitVal = baseDateUnit[unit];

  switch (unitVal) {
    case 'year':
      base.year = base.year + span;
      break;
    case 'month':
      if (base.month < 1 && span < 0) {
        base.month = 11;
        base.year -= 1;
      } else if (base.month > 10 && span > 0) {
        base.month = 0;
        base.year += 1;
      } else {
        base.month = base.month + span;
      }
      break;
    case 'day':
      base.day = base.day + span;
      break;
    default:
      throw new Error('unit传入错误，应为 year|month|day');
  }
  return parseDate(new Date(base.year, base.month, base.day));
};

export const daysInMonth = (choiceDay: baseDate): number => {
  const begin = getFirstDayInMonth(choiceDay);
  const stop = changeDate(choiceDay, baseDateUnit.month, 1);
  const num = (stop.time - begin.time) / DAYTIME;
  return num;
};

export const getcalendarDays = (start: baseDate, firstDay: baseDate): Array<baseDate> => {
  const canlenderList = [];

  const days = daysInMonth(firstDay);

  const canlenderMax = firstDay.week < 5 ? 35 : days === 30 ? 35 : 42;
  for (let i = 0; i < canlenderMax; i++) {
    canlenderList.push(parseDate(start.time + i * DAYTIME));
  }
  return canlenderList;
};

export const isInMonth = (base: baseDate, choiceDay: baseDate): boolean => base.month === choiceDay.month;
export const isToday = (base: baseDate): boolean => base.year === NOW.year && base.month === NOW.month && base.day === NOW.day;
